<?php

//error_reporting(E_ALL);

class DITAFileRef
{
  // TODO turn static functions into ctor+methods.
  //      create subclasses for img, conref and references


  static function createFilesDocument($doc_name='files') 
  {
    $dom = new DomDocument();
    $dom->formatOutput = true;
    $dom->encoding = "utf-8";
    $root = $dom->createElement($doc_name);
    $dom->appendChild($root);
    return $dom;
  }


  static function createProcessor($template)
  {
    $xsl_doc = new DOMDocument;
    $xsl_doc->load($template);
    $xsl = new XSLTProcessor;
    $xsl->importStylesheet($xsl_doc);
    return $xsl;
  }


  static function appendReference($parent, $dirname, $name)
  {
    if (!$parent->ownerDocument)
      return false;

    $path = "$dirname/$name";
    $childdom = new DOMDocument;
    $childdom->load($path);
    if (!$childdom) 
      return false;
    
    
    $dom = $parent->ownerDocument;
    $child = $dom->createElement("file");
    $parent->appendChild($child);

    $child->setAttribute("href", $name);
    $child->setAttribute("type", $childdom->documentElement->localName);

    $titleElm = $childdom->getElementsByTagName("title")->item(0);
    if ($titleElm) {
      $title = $titleElm->nodeValue;
      $child->appendChild($dom->createTextNode($title));
    }
    return true;
  }
}


  function doTransform($xml, $processor, $args)
  {
    for($i = 0; $i < sizeof($args); $i=$i+2)
      $processor->setParameter('', $args[$i], $args[$i+1]);

    return $processor->transformToXML($xml);
  }


  function getData()
  {
    $data = array();

    foreach ($_GET as $key => $value)
      array_push($data, $key, $value);

    foreach ($_POST as $key => $value)
      array_push($data, $key, $value);

    return $data;
  }


  function processReferenceDirectory($dir, $handle, $dom, $parent)
  {
    while (false !== ($file = readdir($handle)))
    {
      $path = "$dir/$file";

      // Skip hidden files, and skip subdirectories
      if (strcasecmp($file, 'Thumbs.db') === 0 
          || strpos($file, '.') === 0
          || !is_file($path))
      {
        continue;
      }
#      else if (childhandle = opendir($path))
#      {
#        $child = $dom->createElement($file);
#        $parent->appendChild($child);
#        processImgDirectory($path, $childhandle, $dom, $child);
#      }
      else
      {
#        $childdom = new DOMDocument;
#        $childdom->::load($path);
#        $title = $childdom->getElementsByTagName("title")->item(0)->nodeValue;
#        $child = $dom->createElement("file");
#        $child->setAttribute("href", substr($path, strlen($dir) + 1));
#        $child->setAttribute("type", $childdom->documentElement->localName);
#        $text = $dom->createTextNode($title);
#        $child->appendChild($text);
#        $parent->appendChild($child);
        DITAFileRef::appendReference($parent, $dir, $file);
      }
    }
  }


  function createReferenceDocument($basedir, $template, $data)
  {
    $dom = DITAFileRef::createFilesDocument();
    $xsl = DITAFileRef::createProcessor($template);

    if ($handle = opendir($basedir)) 
    {
      processReferenceDirectory($basedir, $handle, $dom, $dom->documentElement);
      $docstring = doTransform($dom, $xsl, $data);
      closedir($handle);
      return $docstring;
    }
  }


  function createConrefsDocument($basedir, $template, $data)
  {
    $dom = DITAFileRef::createFilesDocument('content-reference');
    $xsl = DITAFileRef::createProcessor($template);

    if ($handle = opendir($basedir)) 
    {
      processConrefsDirectory($basedir, $handle, $dom, $dom->documentElement);
      $docstring = doTransform($dom, $xsl, $data);
      closedir($handle);
      return $docstring;
    }
    else
    {
      die("<error>Could not read ".$handle."</error>");
    }

  }


  function processConrefsDirectory($dir, $handle, $dom, $parent)
  {
    while (false !== ($file = readdir($handle)))
    {
      $childdir = $dir."/".$file;
      if (strpos($file, '.') === 0 || "Thumbs.db" == $file) 
      {
        // skip hidden files and directories
      }
      //if($file == ".DS_Store"){}
      else if(!strstr($file, ".") && $childhandle = opendir($childdir))
      {
        $child = $dom->createElement($file);
        $parent->appendChild($child);
        //processImgDirectory($childdir, $childhandle, $dom, $child);
      }
      else if($file != "." && $file != ".." && $file != "Thumbs.db" && $file != ".svn")
      {
        $name = $file;//substr($file, 0, strpos($file, "."));
        $childdom = new DOMDocument;
        $childdom->load($dir."/".$file);
        $childdom->encoding = "utf-8";
        $xpath = new DOMXpath($childdom);

        $elements = $xpath->query("//*[@id]");
        
        $prefix_length = strlen($dir) + 1;

        foreach ($elements as $element) 
        {  
          $child = $dom->createElement("reference");
          $path = substr($dir."/".$file , $prefix_length);
          if ($childdom->documentElement->localName == $element->localName) {
            $child->setAttribute("href", "$path");
          } else if ($childdom->documentElement->getAttribute('id')) {
            $topicid =  $childdom->documentElement->getAttribute('id');
            $elementid = $element->getAttribute('id');
            $child->setAttribute("href", "$path#$topicid/$elementid");
          } else {
            // XXX id _should_ be a topic in this case, but we're not checking: 
            $topicid = $element->getAttribute('id');
            $child->setAttribute("href", "$path#$topicid");
          }
          $child->setAttribute("element-name", $element->localName);

          $importNode = $dom->importNode($element);
          $child->appendChild($importNode);

          $parent->appendChild($child);
        }
      }
    }
  }


  function processImgDirectory($dir, $handle, $dom, $parent)
  {
    while (false !== ($file = readdir($handle)))
    {
      $childdir = $dir."/".$file;
      if($file == ".DS_Store"){}
      else if(!strstr($file, ".") && $childhandle = opendir($childdir))
      {
        $child = $dom->createElement($file);
        $parent->appendChild($child);
        processImgDirectory($childdir, $childhandle, $dom, $child);
      }
      else if($file != ".svn" && $file != "." && $file != ".." && $file != "Thumbs.db")
      {
        $name = $file;//substr($file, 0, strpos($file, "."));
        $child = $dom->createElement("image");
        $text = $dom->createTextNode($name);
        $child->appendChild($text);
        $parent->appendChild($child);
      }
    }
  }


  function createImgDocument($basedir, $template, $data)
  {
    $dom = DITAFileRef::createFilesDocument("images");
    $xsl = DITAFileRef::createProcessor($template);

    if ($handle = opendir($basedir))
    {
      processImgDirectory($basedir, $handle, $dom, $dom->documentElement);
      $docstring = doTransform($dom, $xsl, $data);
      closedir($handle);
      return $docstring;
    }
  }
  
  function getElementClassNameList()
  {
    $dom = new DomDocument();
    $dom->formatOutput = true;
    $dom->encoding = "utf-8";
    $root = $dom->createElement("names");
    $dom->appendChild($root);
   
    if ($handle = opendir("../xsd"))
    {

    }  
    return $dom;
  }
  
  function processSchemas($handle, $path)
  {
    while (false !== ($file = readdir($handle)))
    {
		  $childdir = $path."/".$file;
		  if($file == ".DS_Store"){}
		  else if(!strstr($file, ".") && $childhandle = opendir($childdir))
		  {
        processSchemas($childhandle, $childdir);
		  }
      else if($file != "." && $file != ".." && $file != "Thumbs.db" && $file != ".svn")
      {
			  $name = $file;//substr($file, 0, strpos($file, "."));
    	  $childdom = new DOMDocument;
        $childdom->load($dir."/".$file);
    	  $childdom->encoding = "utf-8";
    	  $xpath = new DOMXpath($childdom);
      }
    }  
  }


  function createTextPlusIDDocument($basedir, $template, $data)  
  {
    $dom = DITAFileRef::createFilesDocument("new-text");
    $xsl = DITAFileRef::createProcessor($template);

    return $xsl->transformToXML($dom);
  }


class Navigation 
{
  static function printRecent($dir, $template, $recent_count=5) 
  {
    $doc = DITAFileRef::createFilesDocument('recent-files');

    $form = $doc->createElement('create-form');
    $doc->documentElement->appendChild($form);
    if (isset($_COOKIE['dita_createform_use_sample_v1']) 
           && $_COOKIE['dita_createform_use_sample_v1'] == 1) {
      $use_sample = $doc->createElement('use-sample');
      $form->appendChild($use_sample);
    }
  
    if (isset($_GET['newdoc'])) {
      $filename = $_GET['newdoc'];
      $typename = $_GET['type'];
      $e = $doc->createElement('new-doc');
      $e->appendChild($doc->createTextNode($filename));
      $e->setAttribute('href', $filename);
      $e->setAttribute('type', $typename);
      $form->appendChild($e);
    }

    $files = array();
    $h = opendir($dir);
    if ($h) {
      while (($file = readdir($h)) !== false) {
        $localpath = "$dir/$file";
        
        if (strcasecmp($file, 'Thumbs.db') === 0 
            || strpos($file, '.') === 0
            || strpos($file, 'stub_') === 0)
          continue;
        
        if (is_dir($localpath))
          continue;
        
        $statinfo = stat($localpath);
        $files[] = array('mtime' => $statinfo['mtime'], 'name' => $file);
      }
      closedir($h);
    }

    // Latest are listed first. 
    function timesort($statA, $statB) { return $statB['mtime'] - $statA['mtime']; }

    usort($files, "timesort");

    $files1 = array_splice($files, 0, $recent_count);
    foreach ($files1 as $fileinfo) {
      DITAFileRef::appendReference($doc->documentElement, $dir, $fileinfo['name']);
    }

    $xsl = DITAFileRef::createProcessor($template);
    $xsl->setParameter('', 'dirname', $dir);
    echo $xsl->transformToXML($doc);
  }


  /**
   * Prints a navigation listing
   */
  static function printAllDocuments($path, $template)
  {
    static $MAPEXT = '.ditamap';

    $dir = realpath($path);
    $files = scandir($dir);

    $maps = array();
    $documents = array();

// TODO reuse this directory walker. 
    foreach ($files as $file)
    {
      // Skip "hidden" files: 
      if (strcasecmp($file, 'Thumbs.db') === 0 
          || strpos($file, '.') === 0
          || strpos($file, 'stub_') === 0)
        continue;

      // Put a file in either the maps or the documents lists: 
      $pos = strrpos($file, $MAPEXT);
      if ($pos !== FALSE && $pos === (strlen($file) - strlen($MAPEXT)))
        $maps[] = $file;
      else
        $documents[] = $file;
    }

    $xsl = DITAFileRef::createProcessor($template);
    $xsl->setParameter('', 'dirname', $path);

    foreach ($maps as $mapfilename) {
      $map_doc = new DOMDocument;
      $map_doc->load("${path}/${mapfilename}");
      $xsl->setParameter('', 'filename', $mapfilename);
      echo $xsl->transformToXML($map_doc);
    }
  }
}


class CreateDocument // namespace
{
  static function handlePost() 
  {
    if (isset($_POST['title'])
          && isset($_POST['id']) 
          && isset($_POST['type'])) 
    {
      $id = $_POST['id'];
      $type = $_POST['type'];
      $ext = strstr($_POST['type'], '.');
      $title = $_POST['title'];
      $use_sample = $_POST['use-sample'] == 1 ? true : false;

      $path = "../documents/templates/$type";
      if ($use_sample) {
        // Check to see if sample document exists
        $path2 = preg_replace('/(\.dita|\.ditamap)$/', '-sample$1', $path);
        if (@stat($path2)) {
          $path = $path2;
        }
      }
      $template = new DOMDocument;
      $template->load($path);
      $typename = $template->documentElement->nodeName;
      $xpath = new DOMXPath($template);
      $titleNodes = $xpath->query('//title[1]', $template->documentElement);
      if ($titleNodes->item(0)) {
        if ($titleNodes->item(0)->firstChild) {
          $titleNodes->item(0)->replaceChild(
              $template->createTextNode($title),
              $titleNodes->item(0)->firstChild);
        } else {
          $titleNodes->item(0)->appendChild(
              $template->createTextNode($title));
        }
      }
      $template->documentElement->setAttribute("id", $id);

      if ($template->save("../documents/$id$ext")) { 
        // TODO better permissions checking etc. etc. 
        $url = "http://{$_SERVER['HTTP_HOST']}/{$_SERVER['SCRIPT_NAME']}?newdoc=$id$ext&type=$typename";
        // -- see printRecent, which picks up `newdoc`
        header("Location: $url");
        die("<a href=\"$url\">New document created</a>");
      }
    }
  }

}
